import { HttpUtil } from '../utils/http.util';

/**
 *
 * @param {proxy config} options
 * {
 *   target: 'https://172.35.0.2',
 *   context: [] or string; the match of regex
 *   exclude: [] or string; the match of exclude regex
 * }
 * @returns
 */

function HttpProxy(options = {}) {
    return async (ctx, next) => {
        const url = ctx.request.url;
        const proxyConfig = getProxyConfig(options, url);
        if (proxyConfig) {
            let proxyUrl = proxyConfig.target + url;
            let bodyParams = ctx.request.body;
            let method = ctx.req.method;
            const response: any = await HttpUtil.request({
                url: proxyUrl,
                method,
                body: bodyParams,
                // headers: { Cookie: ctx.header.cookie, 'Content-Type': 'application/json' }
                headers: { ...ctx.header }
            });
            ctx.response.body = response.body;
        } else {
            await next();
        }
    };
};

function getProxyConfig(options = {}, url = ''): any {
    if (!options) {
        return false;
    }
    const configs = Array.isArray(options) ? options : [options];
    let proxyConfig = null;
    for (let i = 0, length = configs.length; i < length; i++) {
        const optionItem = configs[i];
        if (getMatchResult(optionItem, url)) {
            proxyConfig = optionItem;
            break;
        }
    }
    return proxyConfig;
}

function getMatchResult(option: any = {}, url = '') {
    const contextResult = getMatchParams(option.context, url);
    const excludeResult = getMatchParams(option.exclude, url);
    return contextResult && !excludeResult;
}

function getMatchParams(params, url) {
    let result = false;
    try {
        const context = Array.isArray(params) ? params : [params];
        for (let i = 0, length = context.length; i < length; i++) {
            let contextItem = context[i];
            if (typeof (contextItem) === 'string') {
                contextItem = new RegExp(`^${contextItem}[\\s\\S]*$`);
            }
            if (contextItem && contextItem.test(url)) {
                result = true;
                break;
            }
        }
    } catch (error) {
        // TODO
    }
    return result;
}

module.exports = HttpProxy;
